package thread_design;

import java.util.Random;

/**
 * Created with IDEA
 * author:ju bai
 * Date:2021/5/25
 * Time:21:19
 * 自定义阻塞队列
 **/
public class Demo6 {
    static class MyBlockingQueue{
        private int[] values;//实际存储数据的数组
        private int first;//队首
        private int last;//队尾
        private int size;//实际的队列长度

        //构造函数
        public MyBlockingQueue(int initial) {
            //初始化变量
            values = new int[initial];
            first = 0;
            last = 0;
            size = 0;
        }

        //添加元素（添加到队尾）
        public void offer(int val) {
            synchronized (this) {
                //判断边界值
                if (size == values.length) {
                    //队列已满,阻塞等待
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //未满，添加元素到队尾
                /*values[last] = val;
                last++;*/ //合并
                values[last++] = val;
                size++;

                //循环队列，判断是否为最后一个元素
                if (last==values.length) {
                    last=0;//最后一个元素，到第一个元素去，循环
                }

                //尝试唤醒消费者
                this.notify();
            }
        }
        //查询方法
        public int poll() {
            int result = -1;
            synchronized (this) {
                //判断边界值
                if (size == 0) {
                    //队列为空，阻塞等待
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //取元素
                result = values[first++];
                size--;
                //判断是否为最后一个元素
                if (first == values.length) {
                    first = 0;
                }
                //尝试唤醒生产者
                this.notify();
            }
            return result;
        }
    }

    public static void main(String[] args) {

        MyBlockingQueue queue = new MyBlockingQueue(100);

        //创建生产者
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                //每隔500ms生产一条数据
                while (true){
                    int num = new Random().nextInt(10);//0-9的随机数
                    System.out.println("生产了随机数："+num);
                    queue.offer(num);
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        t1.start();

        //创建消费者
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    int result = queue.poll();
                    System.out.println("消费了数据："+result);
                }
            }
        });
        t2.start();
    }
}
